project(DPA)

cmake_minimum_required(VERSION 3.10)

set(ENV{PKG_CONFIG_PATH} "${CMAKE_SOURCE_DIR}:$ENV{PKG_CONFIG_PATH}")

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -DALLOW_EXPERIMENTAL_API -std=c++20 -Wall -Wextra -Werror")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-old-style-cast -Wno-unused-function -Wno-missing-braces")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-address-of-packed-member -Wno-nested-anon-types -Wno-keyword-macro -Wno-deprecated-declarations")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-variadic-macros -Wno-pedantic -Wno-error=pedantic -Wno-vla -Wno-error=vla")

add_definitions(-DDOCA_ALLOW_EXPERIMENTAL_API)
add_definitions(-DFLEXIO_DEV_VER_USED=0)  # 假设 24.9.0 的编码值

find_package(PkgConfig REQUIRED)
pkg_check_modules(DOCA IMPORTED_TARGET doca)
pkg_check_modules(LIBDPDK IMPORTED_TARGET libdpdk)
pkg_check_modules(LIBFLEXIO IMPORTED_TARGET libflexio)

message(STATUS "DOCA_FOUND: ${DOCA_FOUND}")
message(STATUS "LIBDPDK_FOUND: ${LIBDPDK_FOUND}")
message(STATUS "LIBFLEXIO_FOUND: ${LIBFLEXIO_FOUND}")

find_package(gflags REQUIRED)
if (gflags_FOUND)
    message(STATUS "Using gflags ${gflags_VERSION}")
endif ()

if (DOCA_FOUND)
    message(STATUS "DOCA_LIB found")
else ()
    message(FATAL_ERROR "DOCA_LIB not found")
    return()
endif ()

if (LIBDPDK_FOUND)
    message(STATUS "LIBDPDK found")
else ()
    message(FATAL_ERROR "LIBDPDK not found")
    return()
endif ()

if (LIBFLEXIO_FOUND)
    message(STATUS "LIBFLEXIO found")
else ()
    message(FATAL_ERROR "LIBFLEXIO not found")
    return()
endif ()

include_directories("${CMAKE_SOURCE_DIR}")

set(LIBRARIES ${LIBRARIES} PkgConfig::DOCA PkgConfig::LIBDPDK PkgConfig::LIBFLEXIO gflags numa z lz4) 
set(LIBRARIES ${LIBRARIES} ibverbs mlx5)

set(SAMPLE_NAME mt_thread)

file(GLOB FLEXIOSOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
list(APPEND APP_ADDITIONAL_SOURCES ${FLEXIOSOURCES})

set(program_lib_name mt_thread_device)
file(GLOB_RECURSE app_dev_source_file ${CMAKE_CURRENT_SOURCE_DIR}/device/*.c)

set(app_dev_build_dir ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})

string(JOIN "," program_lib_include_dir
    "-I${CMAKE_SOURCE_DIR}"
)

set(program_user_lib -ldoca_dpa_dev -ldoca_dpa_dev_comm)
set(dpacc_build_script ${CMAKE_SOURCE_DIR}/build_dpacc_samples.sh)

file(GLOB DEMO_UTILS ${CMAKE_CURRENT_SOURCE_DIR}/host/*.cc)

set(DYNAMIC_LIB
    ${CMAKE_THREAD_LIBS_INIT}
    ${GFLAGS_LIBRARY}
    glog
    dl
    )

set (DPA_TEST mt_thread_test)
add_executable(${DPA_TEST} ${DEMO_UTILS} ${APP_ADDITIONAL_SOURCES})

add_custom_command(OUTPUT dpacc_${SAMPLE_NAME}
        COMMAND ${dpacc_build_script} ${program_lib_name} \"${app_dev_source_file}\" ${app_dev_build_dir} ${program_lib_include_dir} ${program_user_lib}
)
add_custom_target(
        dpacc_${SAMPLE_NAME}_target ALL
        DEPENDS dpacc_${SAMPLE_NAME}
)

add_dependencies(${DPA_TEST} dpacc_${SAMPLE_NAME}_target)

set(COMMON_LIBS
    ${LIBRARIES}
    ${DYNAMIC_LIB}
    ${app_dev_build_dir}/${program_lib_name}.a
    ibverbs
    mlx5
)

foreach(target_name ${DPA_TEST} )
    if(TARGET ${target_name})
        target_link_libraries(${target_name} ${COMMON_LIBS})
        target_link_directories(${target_name} PUBLIC ${COMMON_LINK_DIRS})
        target_include_directories(${target_name} PUBLIC ${COMMON_INCLUDES})
    endif()
endforeach()